package ubo.master1.jeupoker.gui;

import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.*;
import javax.swing.*;
import ubo.master1.jeupoker.ia.LesActions;
import ubo.master1.jeupoker.ia.GenreJoueur;
import ubo.master1.jeupoker.ia.NiveauFacile;
import ubo.master1.jeupoker.ia.NiveauMoyen;
import ubo.master1.jeupoker.ia.TablePoker;
import ubo.master1.jeupoker.ia.Joueur;

public class Main extends JFrame implements GenreJoueur {

    /** Positionner les composante sur la table1  */
    private GridBagConstraints gc;
    /** La somme a disposition de chacun des joueur au debut */
    private static int STARTING_CASH = 100;
    /** The size of the big blind. */
    private static int BIG_BLIND = 2;
    /** The table1. */
    private TablePoker table1;
    /** The players at the table1. */
    private Map<String, Joueur> players;
    /** Centre de la table1.
    Affichage des Cartes et au dessu les somme de la mise  */
    private TableauDeBord boardPanel;
    /** Controler les actions des utilisateur Exemple : Fold, Check , Raise ... */
    private ControlPrincipal controlPanel;
    /** Dictionnaire de joueurs . */
    private Map<String, PaletteJoueur> playerPanels;
    /** The current dealer's name. */
    private String dealerName;
    /** The current actor's name. */
    private String actorName;
//    final JouerAvecOrdinateur jouerAvecPc = new JouerAvecOrdinateur();
//    ChoiAdversaire adverssaire = new ChoiAdversaire();
    final Sortir sortir = new Sortir();
    private int positionDeX;
    private int positionDeY;
    String nomUtilisateur = "Joueur 1";
    // vaut 0 si premier niveau, 1 si niveau 2 est choisi 
    int NiveauChoisi ;
    int nbrJoueurs = 4;

    public Main() {
        super("Jeu de Poker (IA)");
        super.setSize(1000, 680);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBackground(UIConfiguration.TABLE_COLOR);
        JMenuBar menuBar = new JMenuBar();
        JMenu MenuAction = new JMenu("Action");
        JMenu menuAbout = new JMenu("Aide ?");
        positionDeX = super.getX();
        positionDeY = super.getY();
        menuBar.add(MenuAction);
        menuBar.add(menuAbout);
        JMenuItem menuItemJouer = new JMenuItem("Jouer avec l'ordinateur");
        JMenuItem menuItemSortir = new JMenuItem("Sortir");
        JMenuItem menuItemAbout = new JMenuItem("About");
        MenuAction.add(menuItemJouer);
        MenuAction.add(menuItemSortir);
        menuItemSortir.setToolTipText("Sortir de l'application ");
        menuAbout.add(menuItemAbout);
        super.setJMenuBar(menuBar);
        menuItemJouer.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int rst = JOptionPane.showConfirmDialog(null, "Non implémenté ! Reprendre la partie ?  ", "  Quiter ou reprendre ?", JOptionPane.YES_NO_OPTION);
                if (rst == JOptionPane.OK_OPTION) {
                } else {
                    dispose();
                }
        }
        });
        menuItemSortir.addActionListener(sortir);
       File directorycurr = new File("");
        try {
            String TableBackround = directorycurr.getCanonicalPath();
            setContentPane(new ImageArrierePlan(TableBackround + "\\src\\images\\TableBuckround1.png"));
        } catch (Exception e) {
            System.out.println("Source image non trouvé " + e.getMessage());
        }
        setResizable(true);
        setLocationRelativeTo(null);

        setVisible(true);
        MsgInitialisationJeux();
        setLayout(new GridBagLayout());
        gc = new GridBagConstraints();
        controlPanel = new ControlPrincipal();
        boardPanel = new TableauDeBord(controlPanel);
        addComponent(boardPanel, 1, 1, 1, 2, GridBagConstraints.CENTER);
        players = new LinkedHashMap<String, Joueur>();
        players.put(nomUtilisateur, new Joueur(nomUtilisateur, STARTING_CASH, this));
        for (int i = 1; i <= nbrJoueurs; i++) {
            if(NiveauChoisi == 0){
           
             players.put("Robot" + i, new Joueur("Robo" + i, STARTING_CASH, new NiveauFacile()));
            }else if (NiveauChoisi==1)
                
            {
             players.put("Robot" + i, new Joueur("Robo" + i, STARTING_CASH, new NiveauMoyen()));
            };
            
           // players.put("Robot" + i, new Joueur("Robo" + i, STARTING_CASH, new NiveauFacile()));
         //   players.put("Robot" + i, new Joueur("Robo" + i, STARTING_CASH, new NiveauMoyen()));
        }
        table1 = new TablePoker(BIG_BLIND);
        for (Joueur player : players.values()) {
            table1.addPlayer(player);
        }
        playerPanels = new HashMap<String, PaletteJoueur>();
        int i = 0;
        // Ajouter des utilisateur sur la table de poker
        for (Joueur player : players.values()) {
            PaletteJoueur panel = new PaletteJoueur();
            playerPanels.put(player.getName(), panel);
            switch (i++) {
                case 0:
                    // Joueur position nord sur la table1
                    addComponent(panel, 0, 0, 3, 1, GridBagConstraints.CENTER);
                    break;
                case 1:
                    // Joueur coté droite sur la table1 au sude
                    addComponent(panel, 2, 1, 1, 1, GridBagConstraints.EAST);
                    break;
                case 2:
                    // Joueur coté sud droite.
                    addComponent(panel, 2, 2, 1, 1, GridBagConstraints.EAST);
                    break;
                case 3:
                    // Joueur coté Gauche au sud
                    addComponent(panel, 0, 2, 1, 1, GridBagConstraints.WEST);

                    break;
                case 4:
                    // Joueur coté sur gauche centre
                    addComponent(panel, 0, 1, 1, 1, GridBagConstraints.WEST);
                    break;

                default:

            }
        }
        ControleurIcon tournant = new ControleurIcon("Controlleur.png");
        addComponent(tournant, 0, 3, 3, 1, GridBagConstraints.CENTER);
        validate();
        repaint();
        table1.start();
    }

    private void MsgInitialisationJeux() throws HeadlessException {
        //Une boite de dialogue pour faire entrer les donner initial
        JTextField xField = new JTextField(8);
        xField.setFont(new java.awt.Font("Tahoma", 1, 12));
        JPanel myPanel = new JPanel();
        myPanel.add(new JLabel("Votre nom :"));
        myPanel.add(xField);
        myPanel.add(new JLabel("Nbre adversaires :"));
        JComboBox jComboBox1 = new javax.swing.JComboBox();
        JComboBox jComboBox2 = new javax.swing.JComboBox();
        jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"Un 1", "Deux 2", "Trois 3", "Quatre 4"}));
        jComboBox2.setModel(new javax.swing.DefaultComboBoxModel(new String[]{"Niveau I", "Niveau II"}));
        jComboBox1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            }
        });
        myPanel.add(jComboBox1);
        myPanel.add(jComboBox2);
        myPanel.add(Box.createHorizontalStrut(15)); // a spacer
        int result = JOptionPane.showConfirmDialog(null, myPanel,
                "Initialisation du jeu ", JOptionPane.DEFAULT_OPTION);
        if (result == JOptionPane.OK_OPTION) {
            if (!xField.getText().isEmpty()) {
                nomUtilisateur = xField.getText().toUpperCase();
                NiveauChoisi = jComboBox2.getSelectedIndex();

            } else {
                JOptionPane.showMessageDialog(this, "Vous n'avez pas entrer votre nom , le jeu prend les parametes par defaut ");
            }

            nbrJoueurs = jComboBox1.getSelectedIndex() + 1;


        } else {
            JOptionPane.showMessageDialog(this, "Le jeu prend les parametes par default !");
        }
    }

    public static void main(String[] args) {
        new Main();
    }

    /*
     * (non-Javadoc)
     * @see org.ozsoft.texasholdem.GenreJoueur#joinedTable(int, java.util.List)
     */
    @Override
    public void joinedTable(int bigBlind, List<Joueur> players) {
        for (Joueur player : players) {
            PaletteJoueur playerPanel = playerPanels.get(player.getName());
            if (playerPanel != null) {
                playerPanel.update(player);
            }
        }
    }

    /*
     * (non-Javadoc)
     * @see org.ozsoft.texasholdem.GenreJoueur#messageReceived(java.lang.String)
     */
    @Override
    public void messageReceived(String message) {
        boardPanel.setMessage(message);
        boardPanel.waitForUserInput();
    }

    /*
     * (non-Javadoc)
     * @see org.ozsoft.texasholdem.GenreJoueur#handStarted(org.ozsoft.texasholdem.Joueur)
     */
    @Override
    public void handStarted(Joueur dealer) {
        setDealer(false);
        dealerName = dealer.getName();
        setDealer(true);
    }

    /*
     * (non-Javadoc)
     * @see org.ozsoft.texasholdem.GenreJoueur#actorRotated(org.ozsoft.texasholdem.Joueur)
     */
    @Override
    public void actorRotated(Joueur actor) {
        setActorInTurn(false);
        actorName = actor.getName();
        setActorInTurn(true);
    }

    /*
     * (non-Javadoc)
     * @see org.ozsoft.texasholdem.GenreJoueur#boardUpdated(java.util.List, int, int)
     */
    @Override
    public void boardUpdated(List<LaCart> cards, int bet, int pot) {
        boardPanel.update(cards, bet, pot);
    }

    /*
     * (non-Javadoc)
     * @see org.ozsoft.texasholdem.GenreJoueur#playerUpdated(org.ozsoft.texasholdem.Joueur)
     */
    @Override
    public void playerUpdated(Joueur player) {
        PaletteJoueur playerPanel = playerPanels.get(player.getName());
        if (playerPanel != null) {
            playerPanel.update(player);
        }
    }

    /*
     * (non-Javadoc)
     * @see org.ozsoft.texasholdem.GenreJoueur#playerActed(org.ozsoft.texasholdem.Joueur)
     */
    @Override
    public void playerActed(Joueur player) {
        String name = player.getName();
        PaletteJoueur playerPanel = playerPanels.get(name);
        if (playerPanel != null) {
            playerPanel.update(player);
            LesActions action = player.getAction();
            if (action != null) {
                boardPanel.setMessage(String.format("%s %s.", name, action.getVerb()));
                //FIXME: Determine whether actor is the human player (not by name).
                if (!name.equals("Player")) {
                    boardPanel.waitForUserInput();
                }
            }
        } else {
            throw new IllegalStateException(
                    String.format("No PlayerPanel found for player '%s'", name));
        }
    }

    @Override
    public LesActions act(Set<LesActions> allowedActions) {
        boardPanel.setMessage("Chsoir une action.");
        return controlPanel.getUserInput(allowedActions);
    }

    /**
     * Ajout de composant graphique .
     *
     * @param component
     *           Le composant.
     * @param x
     *           La colone .
     * @param y
     *            La ligne.
     * @param width
     *            Espace entre colonnes .
     * @param height
     *           Espace entre lignes.
     */
    private void addComponent(Component component, int x, int y, int width, int height, int inchor) {
        gc.gridx = x;
        gc.gridy = y;
        gc.gridwidth = width;
        gc.gridheight = height;
        gc.weightx = 0.0;
        gc.weighty = 0.0;

        gc.anchor = inchor;
        gc.fill = GridBagConstraints.NONE;

        getContentPane().add(component, gc);
    }

    /**
     * Retrouver Quel joueur qui a role de jouer.
     *
     * @param isInTurn
     *            Quel joueur qui a le role de jouer.
     */
    private void setActorInTurn(boolean isInTurn) {
        if (actorName != null) {
            PaletteJoueur playerPanel = playerPanels.get(actorName);
            if (playerPanel != null) {
                playerPanel.setInTurn(isInTurn);
            }
        }
    }

    /**
     * déterminer le donneur.
     *
     * @param isDealer
     *           Quel joueur qui est donneur.
     */
    private void setDealer(boolean isDealer) {
        if (dealerName != null) {
            PaletteJoueur playerPanel = playerPanels.get(dealerName);
            if (playerPanel != null) {
                playerPanel.setDealer(isDealer);
            }
        }
    }

    /**
     * @return la positionDeX
     */
    public int getPositionDeX() {
        return positionDeX;
    }

    /**
     * @param détérminer la positionDeX par positionDeX.
     */
    public void setPositionDeX(int positionDeX) {
        this.positionDeX = positionDeX;
    }

    /**
     * @return retrouver la positionDeY
     */
    public int getPositionDeY() {
        return positionDeY;
    }

    /**
     * @param détérminer positionDeY par positionDeY
     */
    public void setPositionDeY(int positionDeY) {
        this.positionDeY = positionDeY;
    }
}

class Sortir extends AbstractAction {

    Sortir() {
    }

    public void actionPerformed(ActionEvent actionEvent) {
        System.exit(1);
    }
}